//! 高性能对象池实现
//! 
//! 核心优化：
//! - RedisCommand对象复用，减少内存分配
//! - 字节缓冲区池化管理
//! - 响应对象复用机制

use std::collections::VecDeque;
use std::sync::Mutex;
use crate::storage::{Command, CommandFactory};

/// 线程安全的对象池
pub struct ObjectPool<T> {
    pool: Mutex<VecDeque<T>>,
    max_size: usize,
    create_fn: Box<dyn Fn() -> T + Send + Sync>,
}

impl<T> ObjectPool<T> {
    /// 创建新的对象池
    pub fn new<F>(max_size: usize, create_fn: F) -> Self 
    where 
        F: Fn() -> T + Send + Sync + 'static 
    {
        Self {
            pool: Mutex::new(VecDeque::with_capacity(max_size)),
            max_size,
            create_fn: Box::new(create_fn),
        }
    }
    
    /// 从池中获取对象
    pub fn get(&self) -> T {
        let mut pool = self.pool.lock().unwrap();
        pool.pop_front().unwrap_or_else(|| (self.create_fn)())
    }
    
    /// 将对象返回到池中
    pub fn put(&self, item: T) {
        let mut pool = self.pool.lock().unwrap();
        if pool.len() < self.max_size {
            pool.push_back(item);
        }
        // 如果池已满，直接丢弃对象，让GC处理
    }
    
    /// 获取池中对象数量
    pub fn size(&self) -> usize {
        self.pool.lock().unwrap().len()
    }
}

/// Redis命令对象池
pub struct RedisCommandPool {
    pool: ObjectPool<PooledRedisCommand>,
}

/// 池化的Redis命令对象（可重置）
#[derive(Debug, Clone)]
pub struct PooledRedisCommand {
    pub name: String,
    pub args: Vec<String>,
    pub connection_id: Option<u64>,
    pub request_id: Option<u64>,
}

impl PooledRedisCommand {
    pub fn new() -> Self {
        Self {
            name: String::with_capacity(16),
            args: Vec::with_capacity(8),
            connection_id: None,
            request_id: None,
        }
    }
    
    /// 重置命令对象以便复用
    pub fn reset(&mut self, name: String, args: Vec<String>) {
        self.name.clear();
        self.name.push_str(&name);
        self.args.clear();
        self.args.extend(args);
        self.connection_id = None;
        self.request_id = None;
    }
    
    /// 设置连接信息
    pub fn set_connection_info(&mut self, connection_id: u64, request_id: u64) {
        self.connection_id = Some(connection_id);
        self.request_id = Some(request_id);
    }
    
    /// 转换为协议层Command
    pub fn to_command(&self) -> Result<Box<dyn Command>, String> {
        CommandFactory::create(self.name.clone(), self.args.clone())
            .map_err(|e| e.to_string())
    }
}

impl RedisCommandPool {
    /// 创建Redis命令池  
    pub fn new(max_size: usize) -> Self {
        Self {
            pool: ObjectPool::new(max_size, PooledRedisCommand::new),
        }
    }
    
    /// 获取命令对象
    pub fn get_command(&self) -> PooledRedisCommand {
        self.pool.get()
    }
    
    /// 归还命令对象
    pub fn return_command(&self, command: PooledRedisCommand) {
        self.pool.put(command);
    }
    
    /// 获取池状态
    pub fn pool_stats(&self) -> (usize, usize) {
        (self.pool.size(), self.pool.max_size)
    }
    
    /// 批量获取命令对象
    pub fn get_commands_batch(&self, count: usize) -> Vec<PooledRedisCommand> {
        (0..count).map(|_| self.get_command()).collect()
    }
    
    /// 批量归还命令对象
    pub fn return_commands_batch(&self, commands: Vec<PooledRedisCommand>) {
        for cmd in commands {
            self.return_command(cmd);
        }
    }
}

/// 字节缓冲区池
pub struct ByteBufferPool {
    pool: ObjectPool<Vec<u8>>,
    buffer_size: usize,
}

impl ByteBufferPool {
    /// 创建字节缓冲区池
    pub fn new(max_size: usize, buffer_size: usize) -> Self {
        Self {
            pool: ObjectPool::new(max_size, move || Vec::with_capacity(buffer_size)),
            buffer_size,
        }
    }
    
    /// 获取缓冲区
    pub fn get_buffer(&self) -> Vec<u8> {
        let mut buffer = self.pool.get();
        buffer.clear();
        buffer.reserve(self.buffer_size);
        buffer
    }
    
    /// 归还缓冲区
    pub fn return_buffer(&self, mut buffer: Vec<u8>) {
        // 如果缓冲区过大，缩小到合理大小
        if buffer.capacity() > self.buffer_size * 2 {
            buffer.shrink_to(self.buffer_size);
        }
        self.pool.put(buffer);
    }
}

/// 全局对象池管理器
pub struct GlobalObjectPools {
    pub command_pool: RedisCommandPool,
    pub read_buffer_pool: ByteBufferPool,
    pub write_buffer_pool: ByteBufferPool,
}

impl GlobalObjectPools {
    /// 创建全局对象池
    pub fn new() -> Self {
        Self {
            command_pool: RedisCommandPool::new(1000),      // 最多1000个命令对象
            read_buffer_pool: ByteBufferPool::new(500, 8192),  // 8KB读缓冲区
            write_buffer_pool: ByteBufferPool::new(500, 8192), // 8KB写缓冲区
        }
    }
    
    /// 获取池统计信息
    pub fn get_stats(&self) -> ObjectPoolStats {
        let (cmd_used, cmd_max) = self.command_pool.pool_stats();
        let (read_used, read_max) = (self.read_buffer_pool.pool.size(), self.read_buffer_pool.pool.max_size);
        let (write_used, write_max) = (self.write_buffer_pool.pool.size(), self.write_buffer_pool.pool.max_size);
        
        ObjectPoolStats {
            command_pool_used: cmd_used,
            command_pool_max: cmd_max,
            read_buffer_pool_used: read_used,
            read_buffer_pool_max: read_max,
            write_buffer_pool_used: write_used,
            write_buffer_pool_max: write_max,
        }
    }
}

/// 对象池统计信息
#[derive(Debug)]
pub struct ObjectPoolStats {
    pub command_pool_used: usize,
    pub command_pool_max: usize,
    pub read_buffer_pool_used: usize,
    pub read_buffer_pool_max: usize,
    pub write_buffer_pool_used: usize,
    pub write_buffer_pool_max: usize,
}

impl Default for GlobalObjectPools {
    fn default() -> Self {
        Self::new()
    }
}

// 为PooledRedisCommand添加默认实现
impl Default for PooledRedisCommand {
    fn default() -> Self {
        Self::new()
    }
}

